<?php

namespace App\Model;

use App\Exceptions\BizException;

class WXPay
{
    const APP_ID = 'wx5d7ef4a9bcad2983';
    const APP_SECRET = '9d05917e7f06933b61cec3acf626aa38';
    const MCH_ID = '1232555502';
    const KEY = '58e8b9503c9d052aefcb5c49dea24ety';
    const UNIFIED_URL = 'https://api.mch.weixin.qq.com/pay/unifiedorder'; // 统一下单地址

    /**
     * 获取jsApi支付参数
     *
     * @param $openid
     * @param $order_num
     * @param $total_fee
     * @param $notify_url
     * @param $body
     * @return array
     */
    public static function getJsPayParams($openid, $order_num, $total_fee, $notify_url, $body = '订单支付')
    {
        $prepay_id = self::unifiedOrder($openid, $order_num, $total_fee, $notify_url, $body);
        $payParams = [
            'appId' => self::APP_ID,
            'timeStamp' => time(),
            'nonceStr' => Common::codeRandom(16, false),
            'package' => 'prepay_id=' . $prepay_id,
            'signType' => 'MD5',
        ];
        $payParams['paySign'] = self::getSign($payParams);
        return $payParams;
    }

    /**
     * 统一下单
     *
     * @param $openid
     * @param $order_num
     * @param $total_fee
     * @param $notify_url
     * @param string $body
     * @return mixed 预支付交易会话标识
     * @throws BizException
     */
    public static function unifiedOrder($openid, $order_num, $total_fee, $notify_url, $body = '订单支付')
    {
        $params = [
            'appid' => self::APP_ID,
            'mch_id' => self::MCH_ID,
            'nonce_str' => Common::codeRandom(16, false),
            'body' => $body,
            'out_trade_no' => $order_num,
            'total_fee' => $total_fee,
            'spbill_create_ip' => $_SERVER['REMOTE_ADDR'],
            'notify_url' => $notify_url,
            'trade_type' => 'JSAPI',
            'openid' => $openid,
        ];
        $params['sign'] = self::getSign($params);
        $xml = Common::array2xml($params);
        $xmlRes = Common::postCurl(self::UNIFIED_URL, $xml);

        if (empty($xmlRes))
            throw new BizException('下单失败');

        $res = Common::simpleXmlToArray($xmlRes);
        if ($res['return_code'] != 'SUCCESS')
            throw new BizException($res['return_msg']);

        if (!empty($res['err_code_des']))
            throw new BizException($res['err_code_des']);

        return $res['prepay_id'];
    }

    /**
     * 接收到支付结果后返回给微信的字串
     *
     * @param bool $success
     * @return string
     */
    public static function returnNotifyXml($success = true)
    {
        $return = [
            'return_code' => $success ? 'SUCCESS' : 'FAIL',
            'return_msg' => $success ? 'OK' : '失败',
        ];
        return Common::array2xml($return);
    }

    public static function getSign($params)
    {
        ksort($params);
        $sign = '';
        foreach ($params as $k => $v) {
            $sign .= $k . '=' . $v . '&';
        }
        $sign .= 'key=' . self::KEY;
        return strtoupper(md5($sign));
    }

    public static function checkSign($data)
    {
        $originSign = $data['sign'];
        unset($data['sign']);
        if ($originSign == self::getSign($data))
            return true;
        return false;
    }
}
